// Created: Dec 11, 2014
//
// Author: wangjw@njits.com.cn (wangjinwen)

#ifndef CHI_CONFIG_H
#define CHI_CONFIG_H

#include <string>
#include <ext/hash_map>
#include <vector>
#include <string.h>

namespace chi {

// 生成string的hash值
struct str_hash {
  size_t operator()(const std::string& str) const {
    return __gnu_cxx::__stl_hash_string(str.c_str());
  }
};
// 字符串比较
struct char_equal {
  bool operator()(const char* s1, const char* s2) const {
    return strcmp(s1, s2) == 0;
  }
};
typedef __gnu_cxx::hash_map<std::string, std::string, str_hash> StrStrMap;
typedef StrStrMap::iterator StrStrMapIter;
typedef __gnu_cxx::hash_map<std::string, StrStrMap*, str_hash> StrMap;
typedef StrMap::iterator StrMapIter;

#define CHI_CONFIG chi::Config::instance()

// 解析配置文件，并将配置文件以key-value的形式存储到内存中
class Config {
 public:
  Config();
  ~Config();

  // 加载一个文件
  int Load(const char* filename);
  // 重新加载配置文件
  //
  // 重复加载同一个配置文件,需要调用此函数.
  // 否则无法把最新的配置加载进来. 
  int Reload(const char* filename);
  // 取一个字符串
  const char* GetString(const char* section,
                        const std::string& key, const char* d = NULL);
  // 取一string列表
  std::vector<const char*> GetStringList(const char* section,
                                         const std::string& key);
  // 取一个整数
  int GetInt(char const* section, const std::string& key, int d = 0);
  // 取一整形列表
  std::vector<int> GetIntList(const char* section, const std::string& key);
  // 取一section下所有key
  int GetSectionKey(const char* section, std::vector<std::string>& keys);
  // 得到所有section的名字
  int GetSectionName(std::vector<std::string>& sections);
  // 完整的配置文件字符串
  std::string ToString();
  // 得到静态实例
  static Config& instance();

 private:
  // 两层map
  StrMap config_map_;

 private:
  // 解析字符串
  int ParseValue(char* str, char* key, char* val);
  char* IsSectionName(char* str);
};

}  // end namespace chi

#endif
